use super::dao::BaseDao;
use crate::db::dao::UpdateDao;
use crate::db::po;
use crate::db::po::candidate_path_segment_list::{ActiveModel, Column, Entity, Model};
use sea_orm::{ColumnTrait, DatabaseConnection};
use sea_query::IntoCondition;

#[derive(Debug, Default, Clone, Eq, PartialEq)]
pub struct Filter {
    pub candidate_path_id: Option<String>,
    pub segment_list_id: Option<String>,
}

impl IntoCondition for Filter {
    fn into_condition(self) -> sea_query::Condition {
        let mut condition = sea_query::Condition::all();

        if let Some(candidate_path_id) = self.candidate_path_id {
            condition = condition.add(Column::CandidatePathId.eq(candidate_path_id));
        }

        if let Some(segment_list_id) = self.segment_list_id {
            condition = condition.add(Column::SegmentListId.eq(segment_list_id));
        }

        condition
    }
}

#[derive(Debug, Default, Clone, PartialEq)]
pub struct UpdateParams {
    pub weight: po::ActiveValue<u32>,
}

impl Into<ActiveModel> for UpdateParams {
    fn into(self) -> ActiveModel {
        ActiveModel {
            id: Default::default(),
            candidate_path_id: Default::default(),
            segment_list_id: Default::default(),
            weight: self.weight,
            create_timestamp_millis: Default::default(),
            update_timestamp_millis: Default::default(),
        }
    }
}

#[async_trait::async_trait]
pub trait CandidatePathSegmentListDao:
    BaseDao<
        Model = Model,
        ActiveModel = ActiveModel,
        Entity = Entity,
        Column = Column,
        Filter = Filter,
    > + UpdateDao<UpdateParams = UpdateParams>
{
}

#[derive(Clone)]
pub struct DefaultCandidatePathSegmentListDao {
    db: DatabaseConnection,
}

impl DefaultCandidatePathSegmentListDao {
    pub fn new(db: DatabaseConnection) -> Self {
        Self { db }
    }
}

#[async_trait::async_trait]
impl BaseDao for DefaultCandidatePathSegmentListDao {
    type Model = Model;
    type ActiveModel = ActiveModel;
    type Entity = Entity;
    type Column = Column;
    type Filter = Filter;

    fn db(&self) -> &DatabaseConnection {
        &self.db
    }
}

#[async_trait::async_trait]
impl UpdateDao for DefaultCandidatePathSegmentListDao {
    type UpdateParams = UpdateParams;
}

#[async_trait::async_trait]
impl CandidatePathSegmentListDao for DefaultCandidatePathSegmentListDao {}
